/*
 ------------------------------------------------------------------------------
 Copyright (C) 2009-2011 Eternal Games.

 This file is part of the Eternal Tech source code.

 The Eternal Tech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Eternal Tech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Eternal Tech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// win_editors.cpp - Editors window creation
//


#include "../qcommon/qcommon.h"
#include "win_local.h"


/*
 ==============================================================================

    LIGHT EDITOR

 ==============================================================================
*/


#define LIGHT_EDITOR_WINDOW_NAME		"Vortex Light Editor"
#define LIGHT_EDITOR_WINDOW_CLASS		"Vortex LightEd"
#define LIGHT_EDITOR_WINDOW_STYLE		(WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)

struct winLightEditor_t {
	lightProperties_t	initialLightProperties;
	lightProperties_t	currentLightProperties;

	void				(*updateLight)(lightProperties_t *);
	void				(*removeLight)(void);
	void				(*closeLight)(void);

	HWND				hWnd;

	HWND				hWndFrame1;
	HWND				hWndFrame2;
	HWND				hWndFrame3;
	HWND				hWndFrame4;

	HWND				hWndX;
	HWND				hWndY;
	HWND				hWndZ;

	HWND				hWndOrigin;
	HWND				hWndOriginX;
	HWND				hWndOriginY;
	HWND				hWndOriginZ;

	HWND				hWndCenter;
	HWND				hWndCenterX;
	HWND				hWndCenterY;
	HWND				hWndCenterZ;

	HWND				hWndAngles;
	HWND				hWndAnglesX;
	HWND				hWndAnglesY;
	HWND				hWndAnglesZ;

	HWND				hWndRadius;
	HWND				hWndRadiusX;
	HWND				hWndRadiusY;
	HWND				hWndRadiusZ;

	HWND				hWndParallel;

	HWND				hWndDetailLevel;
	HWND				hWndDetailLevelValue;

	HWND				hWndPositioning;
	HWND				hWndOriginCenter;

	HWND				hWndXInc;
	HWND				hWndXDec;
	HWND				hWndYInc;
	HWND				hWndYDec;
	HWND				hWndZInc;
	HWND				hWndZDec;

	HWND				hWndCastShadows;

	HWND				hWndColor;
	HWND				hWndColorDisplay;

	HWND				hWndStyle;
	HWND				hWndStyleValue;

	HWND				hWndAlpha;
	HWND				hWndAlphaValue;

	HWND				hWndMaterial;
	HWND				hWndMaterialName;

	HWND				hWndApply;
	HWND				hWndReset;
	HWND				hWndRemove;
	HWND				hWndClose;

	HFONT				hFont;

	HBRUSH				hBrush;

	COLORREF			crCurrent;
	COLORREF			crCustom[16];
};

static winLightEditor_t	lightEditor;


/*
 ==============================================================================

    PROPERTIES

 ==============================================================================
*/


/*
 ==================
 Win_GetLightProperties
 ==================
*/
static void Win_GetLightProperties ()
{
	lightProperties_t   *lightProperties = &lightEditor.currentLightProperties;
	char				string[MAX_OSPATH];
	int					result;

	// Get the current color
	lightProperties->materialParms[0] = GetRValue(lightEditor.crCurrent) * (1.0f/255);
	lightProperties->materialParms[1] = GetGValue(lightEditor.crCurrent) * (1.0f/255);
	lightProperties->materialParms[2] = GetBValue(lightEditor.crCurrent) * (1.0f/255);

	// Read the controls
	if (GetWindowText(lightEditor.hWndOriginX, string, sizeof(string)))
		lightProperties->origin[0] = Str_ToFloat(string);
	else
		lightProperties->origin[0] = 0.0f;

	if (GetWindowText(lightEditor.hWndOriginY, string, sizeof(string)))
		lightProperties->origin[1] = Str_ToFloat(string);
	else
		lightProperties->origin[1] = 0.0f;

	if (GetWindowText(lightEditor.hWndOriginZ, string, sizeof(string)))
		lightProperties->origin[2] = Str_ToFloat(string);
	else
		lightProperties->origin[2] = 0.0f;

	if (GetWindowText(lightEditor.hWndCenterX, string, sizeof(string)))
		lightProperties->center[0] = Str_ToFloat(string);
	else
		lightProperties->center[0] = 0.0f;

	if (GetWindowText(lightEditor.hWndCenterY, string, sizeof(string)))
		lightProperties->center[1] = Str_ToFloat(string);
	else
		lightProperties->center[1] = 0.0f;

	if (GetWindowText(lightEditor.hWndCenterZ, string, sizeof(string)))
		lightProperties->center[2] = Str_ToFloat(string);
	else
		lightProperties->center[2] = 0.0f;

	if (GetWindowText(lightEditor.hWndAnglesX, string, sizeof(string)))
		lightProperties->angles[0] = Str_ToFloat(string);
	else
		lightProperties->angles[0] = 0.0f;

	if (GetWindowText(lightEditor.hWndAnglesY, string, sizeof(string)))
		lightProperties->angles[1] = Str_ToFloat(string);
	else
		lightProperties->angles[1] = 0.0f;

	if (GetWindowText(lightEditor.hWndAnglesZ, string, sizeof(string)))
		lightProperties->angles[2] = Str_ToFloat(string);
	else
		lightProperties->angles[2] = 0.0f;

	if (GetWindowText(lightEditor.hWndRadiusX, string, sizeof(string)))
		lightProperties->radius[0] = Str_ToFloat(string);
	else
		lightProperties->radius[0] = 0.0f;

	if (GetWindowText(lightEditor.hWndRadiusY, string, sizeof(string)))
		lightProperties->radius[1] = Str_ToFloat(string);
	else
		lightProperties->radius[1] = 0.0f;

	if (GetWindowText(lightEditor.hWndRadiusZ, string, sizeof(string)))
		lightProperties->radius[2] = Str_ToFloat(string);
	else
		lightProperties->radius[2] = 0.0f;

	result = SendMessage(lightEditor.hWndParallel, BM_GETCHECK, 0, 0);
	if (result == BST_CHECKED)
		lightProperties->parallel = true;
	else
		lightProperties->parallel = false;

	result = SendMessage(lightEditor.hWndDetailLevelValue, CB_GETCURSEL, 0, 0);
	if (result != CB_ERR)
		lightProperties->detailLevel = Clamp(result, 0, 10);
	else
		lightProperties->detailLevel = 10;

	result = SendMessage(lightEditor.hWndCastShadows, BM_GETCHECK, 0, 0);
	if (result == BST_UNCHECKED)
		lightProperties->noShadows = true;
	else
		lightProperties->noShadows = false;

	result = SendMessage(lightEditor.hWndStyleValue, CB_GETCURSEL, 0, 0);
	if (result != CB_ERR)
		lightProperties->style = Clamp(result, 0, MAX_LIGHTSTYLES-1);
	else
		lightProperties->style = 0;

	if (GetWindowText(lightEditor.hWndAlphaValue, string, sizeof(string)))
		lightProperties->materialParms[3] = Str_ToFloat(string);
	else
		lightProperties->materialParms[3] = 1.0;

	if (GetWindowText(lightEditor.hWndMaterialName, string, sizeof(string)))
		Str_Copy(lightProperties->material, string, sizeof(lightProperties->material));
	else
		Str_Copy(lightProperties->material, "_defaultLight", sizeof(lightProperties->material));
}

/*
 ==================
 Win_SetLightProperties
 ==================
*/
static void Win_SetLightProperties ()
{
	lightProperties_t	*lightProperties = &lightEditor.initialLightProperties;
	byte				r, g, b;

	lightEditor.currentLightProperties = *lightProperties;

	// Set the current color
	r = 255 * Clamp(lightProperties->materialParms[0], 0.0f, 1.0f);
	g = 255 * Clamp(lightProperties->materialParms[1], 0.0f, 1.0f);
	b = 255 * Clamp(lightProperties->materialParms[2], 0.0f, 1.0f);

	lightEditor.crCurrent = RGB(r, g, b);

	// Create the brush
	if (lightEditor.hBrush)
		DeleteObject(lightEditor.hBrush);

	lightEditor.hBrush = CreateSolidBrush(RGB(r, g, b));

	// Update the controls
	SetWindowText(lightEditor.hWndOriginX, Str_VarArgs("%g", lightProperties->origin[0]));
	SetWindowText(lightEditor.hWndOriginY, Str_VarArgs("%g", lightProperties->origin[1]));
	SetWindowText(lightEditor.hWndOriginZ, Str_VarArgs("%g", lightProperties->origin[2]));

	SetWindowText(lightEditor.hWndCenterX, Str_VarArgs("%g", lightProperties->center[0]));
	SetWindowText(lightEditor.hWndCenterY, Str_VarArgs("%g", lightProperties->center[1]));
	SetWindowText(lightEditor.hWndCenterZ, Str_VarArgs("%g", lightProperties->center[2]));

	SetWindowText(lightEditor.hWndAnglesX, Str_VarArgs("%g", lightProperties->angles[0]));
	SetWindowText(lightEditor.hWndAnglesY, Str_VarArgs("%g", lightProperties->angles[1]));
	SetWindowText(lightEditor.hWndAnglesZ, Str_VarArgs("%g", lightProperties->angles[2]));

	SetWindowText(lightEditor.hWndRadiusX, Str_VarArgs("%g", lightProperties->radius[0]));
	SetWindowText(lightEditor.hWndRadiusY, Str_VarArgs("%g", lightProperties->radius[1]));
	SetWindowText(lightEditor.hWndRadiusZ, Str_VarArgs("%g", lightProperties->radius[2]));

	if (lightProperties->parallel)
		SendMessage(lightEditor.hWndParallel, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(lightEditor.hWndParallel, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SendMessage(lightEditor.hWndDetailLevelValue, CB_SETCURSEL, (WPARAM)lightProperties->detailLevel, 0);

	SetWindowText(lightEditor.hWndOriginCenter, "Origin");
	SendMessage(lightEditor.hWndOriginCenter, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	if (lightProperties->noShadows)
		SendMessage(lightEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
	else
		SendMessage(lightEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);

	InvalidateRect(lightEditor.hWndColorDisplay, NULL, FALSE);

	SendMessage(lightEditor.hWndStyleValue, CB_SETCURSEL, (WPARAM)lightProperties->style, 0);

	SetWindowText(lightEditor.hWndAlphaValue, Str_VarArgs("%g", lightProperties->materialParms[3]));

	SetWindowText(lightEditor.hWndMaterialName, lightProperties->material);
}

/*
 ==================
 Win_SetLightPropertiesCallbacks
 ==================
*/
void Win_SetLightPropertiesCallbacks (void (*updateLight)(lightProperties_t *), void (*removeLight)(), void (*closeLight)())
{
	lightEditor.updateLight = updateLight;
	lightEditor.removeLight = removeLight;
	lightEditor.closeLight = closeLight;
}

/*
 ==================
 Win_AddLightPropertiesMaterial
 ==================
*/
void Win_AddLightPropertiesMaterial (const char *name)
{
	if (!lightEditor.hWnd)
		return;

	if (!Str_ICompareChars("lights/", name, 7))
	{
		SendMessage(lightEditor.hWndMaterialName, CB_ADDSTRING, 0, (LPARAM)name);
		return;
	}

	if (!Str_ICompareChars("fogs/", name, 5))
	{
		SendMessage(lightEditor.hWndMaterialName, CB_ADDSTRING, 0, (LPARAM)name);
		return;
	}
}

/*
 ==================
 Win_EditLightProperties
 ==================
*/
void Win_EditLightProperties (lightProperties_t *lightProperties)
{
	if (!lightEditor.hWnd)
	{
		lightEditor.closeLight();
		return;
	}

	// Save the initial light properties
	lightEditor.initialLightProperties = *lightProperties;

	// Set the current light properties
	Win_SetLightProperties();

	// Show the window
	ShowWindow(lightEditor.hWnd, SW_SHOW);
	UpdateWindow(lightEditor.hWnd);
	SetForegroundWindow(lightEditor.hWnd);
	SetFocus(lightEditor.hWnd);
}

/*
 ==================
 Win_ApplyLightProperties
 ==================
*/
void Win_ApplyLightProperties ()
{
	if (!lightEditor.hWnd)
	{
		lightEditor.closeLight();
		return;
	}

	// Get the current light properties
	Win_GetLightProperties();

	// Update the light
	lightEditor.updateLight(&lightEditor.currentLightProperties);
}


/*
 ==============================================================================

    WINDOW PROCEDURE

 ==============================================================================
*/


/*
 ==================
 Win_LightEditorWindowProc
 ==================
*/
static LRESULT CALLBACK Win_LightEditorWindowProc (__in HWND hWnd, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam)
{
	switch (uMsg){
	case WM_CREATE:
		winMain.hWndLightEditor = hWnd;

		break;
	case WM_DESTROY:
		winMain.hWndLightEditor = NULL;

		break;
	case WM_CLOSE:
		ShowWindow(lightEditor.hWnd, SW_HIDE);

		lightEditor.closeLight();

		return 0;
	case WM_COMMAND:
		if (HIWORD(wParam) == BN_CLICKED)
		{
			CHOOSECOLOR   chooseColor;
			char		  string[MAX_PATH_LENGTH];

			if ((HWND)lParam == lightEditor.hWndOriginCenter)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED)
					SetWindowText(lightEditor.hWndOriginCenter, "Center");
				else
					SetWindowText(lightEditor.hWndOriginCenter, "Origin");

				break;
			}

			if ((HWND)lParam == lightEditor.hWndXInc)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED)
				{
					GetWindowText(lightEditor.hWndCenterX, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterX, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginX, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginX, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndXDec)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED)
				{
					GetWindowText(lightEditor.hWndCenterX, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterX, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginX, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginX, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndYInc)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED){
					GetWindowText(lightEditor.hWndCenterY, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterY, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginY, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginY, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndYDec)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED){
					GetWindowText(lightEditor.hWndCenterY, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterY, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginY, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginY, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndZInc)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED)
				{
					GetWindowText(lightEditor.hWndCenterZ, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterZ, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginZ, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginZ, Str_VarArgs("%g", Str_ToFloat(string) + 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndZDec)
			{
				if (SendMessage(lightEditor.hWndOriginCenter, BM_GETCHECK, 0, 0) == BST_CHECKED)
				{
					GetWindowText(lightEditor.hWndCenterZ, string, sizeof(string));
					SetWindowText(lightEditor.hWndCenterZ, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}
				else
				{
					GetWindowText(lightEditor.hWndOriginZ, string, sizeof(string));
					SetWindowText(lightEditor.hWndOriginZ, Str_VarArgs("%g", Str_ToFloat(string) - 1.0f));
				}

				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndColor)
			{
				chooseColor.lStructSize = sizeof(CHOOSECOLOR);
				chooseColor.hwndOwner = lightEditor.hWnd;
				chooseColor.hInstance = NULL;
				chooseColor.rgbResult = lightEditor.crCurrent;
				chooseColor.lpCustColors = lightEditor.crCustom;
				chooseColor.Flags = CC_FULLOPEN | CC_RGBINIT;
				chooseColor.lCustData = 0;
				chooseColor.lpfnHook = NULL;
				chooseColor.lpTemplateName = NULL;

				if (ChooseColor(&chooseColor))
				{
					lightEditor.crCurrent = chooseColor.rgbResult;

					if (lightEditor.hBrush)
						DeleteObject(lightEditor.hBrush);

					lightEditor.hBrush = CreateSolidBrush(chooseColor.rgbResult);

					InvalidateRect(lightEditor.hWndColorDisplay, NULL, FALSE);
				}

				break;
			}

			if ((HWND)lParam == lightEditor.hWndApply)
			{
				Win_GetLightProperties();

				lightEditor.updateLight(&lightEditor.currentLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndReset)
			{
				Win_SetLightProperties();

				lightEditor.updateLight(&lightEditor.initialLightProperties);
				break;
			}

			if ((HWND)lParam == lightEditor.hWndRemove)
			{
				ShowWindow(lightEditor.hWnd, SW_HIDE);

				lightEditor.removeLight();
				break;
			}

			if ((HWND)lParam == lightEditor.hWndClose)
			{
				ShowWindow(lightEditor.hWnd, SW_HIDE);

				lightEditor.closeLight();
				break;
			}
		}

		break;
	case WM_CTLCOLORSTATIC:
		if ((HWND)lParam == lightEditor.hWndColorDisplay)
		{
			SetBkColor((HDC)wParam, lightEditor.crCurrent);
			SetTextColor((HDC)wParam, lightEditor.crCurrent);

			return (LONG)lightEditor.hBrush;
		}

		break;
	}

	// Pass all unhandled messages to DefWindowProc
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


/*
 ==============================================================================

    WINDOW CREATION

 ==============================================================================
*/


/*
 ==================
 Win_CreateLightEditorWindow
 ==================
*/
void *Win_CreateLightEditorWindow ()
{
	WNDCLASSEX   wndClass;
	RECT		 rect;
	int			 screenWidth, screenHeight;
	int			 x, y, w, h;
	int          i;

	// Calculate window position and dimensions
	screenWidth = GetSystemMetrics(SM_CXSCREEN);
	screenHeight = GetSystemMetrics(SM_CYSCREEN);

	rect.left = (screenWidth - 392) / 2;
	rect.top = (screenHeight - 288) / 2;
	rect.right = rect.left + 392;
	rect.bottom = rect.top + 288;

	AdjustWindowRectEx(&rect, LIGHT_EDITOR_WINDOW_STYLE, FALSE, 0);

	x = rect.left;
	y = rect.top;
	w = rect.right - rect.left;
	h = rect.bottom - rect.top;

	// Register the window class
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = 0;
	wndClass.lpfnWndProc = Win_LightEditorWindowProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = winMain.hInstance;
	wndClass.hIcon = LoadIcon(winMain.hInstance, MAKEINTRESOURCE(IDI_ICON1));
	wndClass.hIconSm = NULL;
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = LIGHT_EDITOR_WINDOW_CLASS;

	if (!RegisterClassEx(&wndClass))
	{
		MessageBox(NULL, "Could not register light editor window class", "ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL);
		exit(0);

		return NULL;
	}

	// Create the window
	lightEditor.hWnd = CreateWindowEx(0, LIGHT_EDITOR_WINDOW_CLASS, LIGHT_EDITOR_WINDOW_NAME, LIGHT_EDITOR_WINDOW_STYLE, x, y, w, h, NULL, NULL, winMain.hInstance, NULL);
	if (!lightEditor.hWnd)
	{
		UnregisterClass(LIGHT_EDITOR_WINDOW_CLASS, winMain.hInstance);

		MessageBox(NULL, "Could not create light editor window", "ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL);
		exit(0);

		return NULL;
	}

	// Create the controls
	lightEditor.hWndFrame1 = CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 3, 178, 206, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndFrame2 = CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 194, 3, 190, 103, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndFrame3 = CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 194, 110, 190, 99, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndFrame4 = CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 212, 376, 35, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 54, 12, 40, 14, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 98, 12, 40, 14, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 142, 12, 40, 14, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndOrigin = CreateWindowEx(0, "STATIC", "Origin", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 29, 38, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndOriginX = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 54, 26, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndOriginY = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 98, 26, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndOriginZ = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 142, 26, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndCenter = CreateWindowEx(0, "STATIC", "Center", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 59, 38, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndCenterX = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 54, 56, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndCenterY = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 98, 56, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndCenterZ = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 142, 56, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndAngles = CreateWindowEx(0, "STATIC", "Angles", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 89, 38, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndAnglesX = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 54, 86, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndAnglesY = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 98, 86, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndAnglesZ = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 142, 86, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndRadius = CreateWindowEx(0, "STATIC", "Radius", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 119, 38, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndRadiusX = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 54, 116, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndRadiusY = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 98, 116, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndRadiusZ = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 142, 116, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndParallel = CreateWindowEx(0, "BUTTON", "Parallel", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 12, 158, 170, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndDetailLevel = CreateWindowEx(0, "STATIC", "Detail Level", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 188, 120, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndDetailLevelValue = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 136, 184, 46, 200, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndPositioning = CreateWindowEx(0, "STATIC", "Positioning:", WS_CHILD | WS_VISIBLE | SS_LEFT, 198, 12, 182, 14, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndOriginCenter = CreateWindowEx(0, "BUTTON", "Origin", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX | BS_PUSHLIKE, 198, 58, 46, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndXInc = CreateWindowEx(0, "BUTTON", "X+", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 312, 58, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndXDec = CreateWindowEx(0, "BUTTON", "X-", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 264, 58, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndYInc = CreateWindowEx(0, "BUTTON", "Y+", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 288, 34, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndYDec = CreateWindowEx(0, "BUTTON", "Y-", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 288, 82, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndZInc = CreateWindowEx(0, "BUTTON", "Z+", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 360, 34, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndZDec = CreateWindowEx(0, "BUTTON", "Z-", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 360, 82, 20, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndCastShadows = CreateWindowEx(0, "BUTTON", "Cast Shadows", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 198, 119, 182, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndColor = CreateWindowEx(0, "BUTTON", "Color", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 198, 154, 46, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndColorDisplay = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_SUNKEN, 248, 154, 38, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndStyle = CreateWindowEx(0, "STATIC", "Style", WS_CHILD | WS_VISIBLE | SS_RIGHT, 292, 158, 38, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndStyleValue = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST, 334, 154, 46, 200, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndAlpha = CreateWindowEx(0, "STATIC", "Alpha / Distance to Opaque", WS_CHILD | WS_VISIBLE | SS_RIGHT, 198, 187, 138, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndAlphaValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 340, 184, 40, 20, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndMaterial = CreateWindowEx(0, "STATIC", "Material", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 225, 82, 16, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndMaterialName = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL, 98, 222, 282, 200, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	lightEditor.hWndApply = CreateWindowEx(0, "BUTTON", "Apply", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 8, 256, 80, 24, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndReset = CreateWindowEx(0, "BUTTON", "Reset", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 92, 256, 80, 24, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndRemove = CreateWindowEx(0, "BUTTON", "Remove", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 220, 256, 80, 24, lightEditor.hWnd, NULL, winMain.hInstance, NULL);
	lightEditor.hWndClose = CreateWindowEx(0, "BUTTON", "Close", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 304, 256, 80, 24, lightEditor.hWnd, NULL, winMain.hInstance, NULL);

	// Create and set the font
	lightEditor.hFont = CreateFont(14, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "MS Sans Serif");

	SendMessage(lightEditor.hWndFrame1, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndFrame2, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndFrame3, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndFrame4, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndX, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndY, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndZ, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndOrigin, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndOriginX, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndOriginY, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndOriginZ, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndCenter, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndCenterX, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndCenterY, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndCenterZ, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndAngles, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndAnglesX, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndAnglesY, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndAnglesZ, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndRadius, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndRadiusX, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndRadiusY, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndRadiusZ, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndParallel, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndDetailLevel, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndDetailLevelValue, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndPositioning, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndOriginCenter, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndXInc, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndXDec, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndYInc, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndYDec, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndZInc, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndZDec, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndCastShadows, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndColor, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndColorDisplay, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndStyle, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndStyleValue, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndAlpha, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndAlphaValue, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndMaterial, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndMaterialName, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	SendMessage(lightEditor.hWndApply, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndReset, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndRemove, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);
	SendMessage(lightEditor.hWndClose, WM_SETFONT, (WPARAM)lightEditor.hFont, FALSE);

	// Fill the combo boxes
	for (i = 0; i <= 10; i++)
		SendMessage(lightEditor.hWndDetailLevelValue, CB_ADDSTRING, 0, (LPARAM)Str_VarArgs("%i", i));

	for (i = 0; i < MAX_LIGHTSTYLES; i++)
		SendMessage(lightEditor.hWndStyleValue, CB_ADDSTRING, 0, (LPARAM)Str_VarArgs("%i", i));

	SendMessage(lightEditor.hWndMaterialName, CB_ADDSTRING, 0, (LPARAM)"_defaultLight");

	// Set text limit for material combo box
	SendMessage(lightEditor.hWndMaterialName, CB_LIMITTEXT, (WPARAM)(MAX_OSPATH-1), 0);

	// Create the brush
	lightEditor.hBrush = CreateSolidBrush(RGB(255, 255, 255));

	// Set the current color
	lightEditor.crCurrent = RGB(255, 255, 255);

	// Set the custom colors
	for (i = 0; i < 16; i++)
		lightEditor.crCustom[i] = RGB(255, 255, 255);

	return lightEditor.hWnd;
}


/*
 ==============================================================================

    INITIALIZATION AND SHUTDOWN

 ==============================================================================
*/


/*
 ==================
 Win_ShutdownLightEditor
 ==================
*/
void Win_ShutdownLightEditor ()
{
	if (!lightEditor.hWnd)
		return;

	if (lightEditor.hBrush)
		DeleteObject(lightEditor.hBrush);

	if (lightEditor.hFont)
		DeleteObject(lightEditor.hFont);

	ShowWindow(lightEditor.hWnd, SW_HIDE);
	DestroyWindow(lightEditor.hWnd);
	UnregisterClass(LIGHT_EDITOR_WINDOW_CLASS, winMain.hInstance);

	memset(&lightEditor, 0, sizeof(winLightEditor_t));
}